// 1. 引入sme-router
import SMERouter from 'sme-router'
// 引入axios实例
import request from './utils/fetch'
// 引入格式化的js库
import moment from 'moment'

// 引入模板
// 返回的index是一个函数,index函数调用的返回值就是模板中html结构字符串
// import index from './views/index'
// import login from './views/login'
import index from '@v/index'
import login from '@v/login'
import advList from '@v/advList'
import adminList from '@v/adminList'
// console.log(index())

// 引入验证token的函数
import vertifyToken from './api/vertifyToken'

// 2. 创建router对象
// root 是index.html中写死的一个节点的id名
// 注意: smeRouter默认是hash模式,root后面添加html5则变为history模式
// hash模式改变的是hash值,路径没有变,路径一直是/
// history模式改变的就是路径
const router = new SMERouter('root', 'html5')
// 把router对象暴露到全局
window.router = router
// 将moment暴露到全局
window.moment = moment

// 全局变量,用于存储要修改的数据的id
let updateId = ''

// 3. 配置前端路由规则
// router.route('/路径',回调函数) //回调函数中返回对应要渲染的视图
router.route('/index', async function (req, res, next) {
  const result = await vertifyToken()
  // console.log(result)
  if (result.status === 'fail') {
    toastr.error(result.message)
    res.redirect('/login')
    return
  }
  // console.log(res.subRoute()) //<div id="__sub-route-view"></div> 这是标签专门用来渲染二级路由的内容. 需要在一级路由的html结构中渲染才会生效
  // next是一个函数,用来处理当前路由下面的子路由的,当路径为/index/advList的时候,只有写了这个next,才会展示一级路由
  // console.log(req.url)
  next(
    index({
      // 把渲染二级路由的标签,传递到模板中,注意:需要在模板中把这个标签渲染出来
      subRoute: res.subRoute(),
      url: req.url, // req.url 是当前浏览器地址栏中的路径
      username: req.body, // req.body是router.go传递过来的用户名
    })
  )

  // 获取退出按钮,并完成退出逻辑
  $('#logoutBtn').on('click', async function () {
    // 拿到当前用户的id
    const id = localStorage.getItem('id')
    // 发送请求,将id上传给服务器,让服务器删除数据库的token
    await request.post('/logout', { id })
    // 删除浏览器端本地缓存中的token
    localStorage.setItem('token', '')
    // 提示用户
    toastr.success('退出成功')
    // 切换到login页面
    router.go('/login')
  })
})

// 配置二级路由的路由规则
router.route('/index/adminList', async function (req, res) {
  const vertifyResult = await vertifyToken()
  // console.log(result)
  if (vertifyResult.status === 'fail') {
    toastr.error(vertifyResult.message)
    res.redirect('/login')
    return
  }
  // 当管理员列表要展示的时候,这个回调要执行
  // 发送请求,获取管理员数据
  // 如果要让开发服务器代理: 1. 请求的域名和端口号应该是开发服务器的 2. 路径要以/dev-api开头
  const result = await request.get('/findAdmins')
  res.render(adminList(result))
})
router.route('/index/advList', async function (req, res) {
  // 验证token
  const vertifyResult = await vertifyToken()
  // console.log(result)
  if (vertifyResult.status === 'fail') {
    toastr.error(vertifyResult.message)
    res.redirect('/login')
    return
  }

  // 获取广告数据
  const result = await request.get('/getAdvs')
  res.render(advList(result))

  // 获取模态框的保存按钮,注册点击事件.并发送请求
  $('#saveAdv').on('click', async function () {
    // 注意: 由于修改广告和添加广告使用了同一个模态框,所以保存按钮也是同一个
    //我们需要判断,当前事件处理函数触发的时候,到底是添加还是修改
    // 如果模态框标题是添加广告则执行添加操作,如果是修改广告,则执行修改操作
    // console.log($('.modal-title').text())
    // 创建formdata实例
    const form = $('#form')[0]
    // 注意: form表单中的每一个表单中必须有name属性,这样formdata中才会有对应的数据
    const formdata = new FormData(form)
    if ($('.modal-title').text() === '添加广告') {
      // 发送请求,添加广告

      await request.post('/addAdv', formdata, {
        // 使用axios发送请求,上传formdata数据,必须要在请求头中修改content-type的值
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      })
      toastr.success('广告添加成功')
    } else {
      // 修改
      // 要将被修改的数据的id,添加到formdata上面
      formdata.append('id', updateId)
      // console.log(formdata.has('file'))
      // formdata.delete('file')
      // console.log(formdata.has('file'))
      // 如果不修改图片的情况下,formdata中依然存在file这个字段
      await request.post('/updateAdv', formdata, {
        // 使用axios发送请求,上传formdata数据,必须要在请求头中修改content-type的值
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      })
      toastr.success('广告修改成功')
    }
    // 重新打开广告界面
    router.go('/index/advList')
  })

  // 添加广告时,图片预览的逻辑
  // 找到上传图片的表单元素,注册change事件
  $('#file').on('change', function () {
    // console.log('123')
    // 生成reader对象,这个reader对象用于读取我们选中的图片
    const reader = new FileReader()

    // 要将选中的图片转成base64
    // 先获取到选中的图片
    const file = $('#file')[0].files[0]
    // 注意: 如果我们没有选择图片,则file为undefined. 执行readAsDataURL会报错,所以我们用trycatch把转换的代码包裹起来
    try {
      // 进行转换. 这个方法没有返回值,转换的结果要在reader.onload事件中获取
      reader.readAsDataURL(file)

      // // 获取转换的结果
      reader.onload = function (e) {
        // console.log(e.target.result) // e.target.result拿到的就是图片的base64
        // 获取要展示预览图的img的dom对象
        $('#preShow')[0].style.display = 'block'
        $('#preShow')[0].src = e.target.result
      }
    } catch (error) {
      // 如果没有选择图片,则预览图片隐藏
      $('#preShow')[0].style.display = 'none'
    }
  })

  // 删除广告的代码
  $('.delBtn').on('click', async function (e) {
    console.log(123)
    // 获取点击的删除按钮所对应的那条数据的id
    const id = e.target.id
    // 发送请求删除数据
    await request.post('/delAdv', { id })
    toastr.success('删除成功')
    // 发送请求获取最新数据
    // const result = await request.get('/getAdvs')
    // // 重新渲染广告列表. 注意:如果重新渲染,会生成新dom覆盖旧dom.原来注册的事件就没有了
    // res.render(advList(result))
    router.go('/index/advList')
  })

  // 修改按钮点击事件
  $('.updateBtn').on('click', async function (e) {
    // 让模态框展示
    $('#modal-default').css({ display: 'block' }).addClass('show')
    // 修改模态框的标题
    $('.modal-title').text('修改广告')
    // 获取当前数据的id
    // 获取自定义属性data-id的值
    const id = e.target.dataset.id
    // 根据当前id获取广告数据,并添加到表单中
    const adv = await request.get('/getOneAdv', {
      params: {
        id,
      },
    })
    // 把对应的信息,添加到表单中
    // 广告标题
    $('#inputEmail3').val(adv.advTitle)
    // 广告类别
    $('#inputPassword3').val(adv.advCate)
    // 广告链接
    $('#inputPassword4').val(adv.advLink)
    // 预览图片
    $('#preShow')[0].src = adv.advImg

    // 将要修改的数据的id存储到全局
    updateId = id
  })

  // 点击模态框的x按钮和取消按钮隐藏模态框
  $('#cancel-x,#cancel').on('click', function () {
    $('#modal-default').css({ display: 'none' }).removeClass('show')
  })

  // 点击添加广告按钮,清空表单项, 修改标题
  $('#addBtn').on('click', function () {
    $('.modal-title').text('添加广告')
    // 清空表单
    $('#inputEmail3').val('')
    // 广告类别
    $('#inputPassword3').val('')
    // 广告链接
    $('#inputPassword4').val('')
    // 预览图片
    $('#preShow')[0].src = ''
  })
})
router.route('/login', function (req, res) {
  res.render(login())
  // res.render执行之后,页面才渲染完成
  // 登录功能
  $('#loginBtn').on('click', async function (e) {
    e.preventDefault() // 阻止form表单中提交按钮的默认行为
    // 1. 获取表单中的用户名和密码
    const username = $('input[type=text]').val().trim()
    const password = $('input[type=password]').val().trim()
    console.log(username, password)
    // 2. 对用户名和密码进行校验.校验通过则发送请求,校验不通过则提示用户
    if (username && password) {
      // 校验通过,都写了
      // 发送请求
      const result = await request.post('/login', {
        username,
        password,
      })
      // console.log(result)
      // 注意: 不管登录是否成功,代码执行到这里,表示的是请求成功了
      // 所以我们还要通过服务器响应的status,来判断登录是否成功
      // status如果是fail就是不成功,如果是ok才表示登录成功
      if (result.status === 'fail') return toastr.error(result.message)
      // 将token存储起来
      localStorage.setItem('token', result.token)
      // 把当前登录用户的id也存起来
      localStorage.setItem('id', result.id)
      // 提示用户登录成功
      toastr.success(result.message)
      // 让页面切换到首页
      // router.go的第二个参数,可以往目标路由中传递数据. 通过目标路由的req.body获取
      router.go('/index', username)
    } else {
      // 校验不通过,可能有一个没有,提示用户
      // toastr是我们引入的一个js文件中提供的全局对象
      toastr.error('用户名和密码都必须填写')
    }
  })
})
router.route('/404', function (req, res) {
  res.render('找不到您想要的页面')
})
// 以上的路由都匹配不上的时候,就会执行*.重定向到404
router.route('*', function (req, res) {
  // 重定向把浏览器地址栏的路径改成404
  res.redirect('/login')
})
